﻿using System;
using Microsoft.Crm.Sdk;
using NUnit.Framework;

namespace Microsoft.CRM.ThirdParty.Extensions.Unit.Tests
{

    [TestFixture]
    public class DynamicEntityExtensionTests
    {
        [Test]
        public void When_asking_for_the_string_value_of_a_property_that_does_not_exist_an_empty_string_should_be_returned()
        {
            DynamicEntity entity = GetEmptyEntityForExceptionTests();
            Assert.AreEqual(String.Empty, entity.GetStringValueOfPropertyFor("name"));
        }

        [Test]
        public void When_asking_for_the_string_value_of_a_property_that_does_exist_a_non_empty_string_should_be_returned()
        {
            DynamicEntity entity = GetValidEntityForTests();
            Assert.AreNotEqual(String.Empty, entity.GetStringValueOfPropertyFor("stringproperty"));
        }

        [Test]
        public void When_asking_for_the_integer_value_of_a_property_that_does_not_exist_zero_should_be_returned()
        {
            DynamicEntity entity = GetEmptyEntityForExceptionTests();
            Assert.AreEqual(int.MinValue, entity.GetIntegerValueFor("number"));
        }

        [Test]
        public void When_asking_for_the_integer_value_of_a_property_that_does_exist_a_valid_integer_should_be_returned()
        {
            DynamicEntity entity = GetValidEntityForTests();
            Assert.AreEqual(1, entity.GetIntegerValueFor("numberproperty"));
        }

        [Test]
        public void When_asking_for_the_guid_value_of_a_property_as_a_string_that_does_not_exist_an_empty_string_should_be_returned()
        {
            DynamicEntity entity = GetEmptyEntityForExceptionTests();
            Assert.AreEqual(String.Empty, entity.GetKeyAsStringValueOfPropertyFor("key"));
        }

        [Test]
        public void When_asking_for_the_guid_value_of_a_property_as_a_string_that_does_exist_a_non_empty_string_should_be_returned()
        {
            DynamicEntity entity = GetValidEntityForTests();
            Assert.AreNotEqual(String.Empty, entity.GetKeyAsStringValueOfPropertyFor("keyproperty"));
        }

        [Test]
        public void When_asking_for_the_guid_value_of_a_property_that_does_not_exist_an_empty_guid_should_be_returned()
        {
            DynamicEntity entity = GetEmptyEntityForExceptionTests();
            Assert.AreEqual(Guid.Empty, entity.GetKeyAsGuidValueOfPropertyFor("key"));
        }

        [Test]
        public void When_asking_for_the_guid_value_of_a_property_that_does_exist_a_non_empty_guid_should_be_returned()
        {
            DynamicEntity entity = GetValidEntityForTests();
            Assert.AreNotEqual(Guid.Empty, entity.GetKeyAsGuidValueOfPropertyFor("keyproperty"));
        }

        [Test]
        public void When_asking_for_the_integer_value_of_a_picklist_property_that_does_not_exist_integer_minvalue_should_be_returned()
        {
            DynamicEntity entity = GetEmptyEntityForExceptionTests();
            Assert.AreEqual(Int32.MinValue, entity.GetPicklistValueOfPropertyFor("number"));
        }

        [Test]
        public void When_asking_for_the_integer_value_of_a_picklist_property_that_does_exist_the_correct_integer_value_should_be_returned()
        {
            DynamicEntity entity = GetValidEntityForTests();
            Assert.AreEqual(1, entity.GetPicklistValueOfPropertyFor("picklistproperty"));
        }

        [Test]
        public void When_asking_for_the_string_value_of_a_picklist_property_that_does_not_exist_empty_should_be_returned()
        {
            DynamicEntity entity = GetEmptyEntityForExceptionTests();
            Assert.AreEqual(String.Empty, entity.GetPicklistNameOfPropertyFor("number"));
        }

        [Test]
        public void When_asking_for_the_string_value_of_a_picklist_property_that_does_exist_the_correct_string_value_should_be_returned()
        {
            DynamicEntity entity = GetValidEntityForTests();
            Assert.AreEqual("Test Name", entity.GetPicklistNameOfPropertyFor("picklistproperty"));
        }

        [Test]
        public void When_asking_for_the_float_value_of_a_property_that_does_not_exist_zero_should_be_returned()
        {
            DynamicEntity entity = GetEmptyEntityForExceptionTests();
            Assert.AreEqual(double.MinValue, entity.GetFloatValueFor("number"));
        }

        [Test]
        public void When_asking_for_the_float_value_of_a_property_that_does_exist_the_correct_amount_should_be_returned()
        {
            DynamicEntity entity = GetValidEntityForTests();
            Assert.AreEqual(100f, entity.GetFloatValueFor("floatproperty"));
        }

        [Test]
        public void When_asking_for_the_double_value_of_a_property_that_does_not_exist_zero_should_be_returned()
        {
            DynamicEntity entity = GetEmptyEntityForExceptionTests();
            Assert.AreEqual(double.MinValue, entity.GetDoubleValueFor("number"));
        }

        [Test]
        public void When_asking_for_the_decimal_value_of_a_property_that_does_not_exist_zero_should_be_returned()
        {
            DynamicEntity entity = GetEmptyEntityForExceptionTests();
            Assert.AreEqual(decimal.MinValue, entity.GetDecimalValueFor("number"));
        }

        [Test]
        public void When_asking_for_the_decimal_value_of_a_property_that_does_exist_the_correct_amount_should_be_returned()
        {
            DynamicEntity entity = GetValidEntityForTests();
            Assert.AreEqual(100m, entity.GetDecimalValueFor("decimalproperty"));
        }

        [Test]
        public void When_asking_for_the_money_value_of_a_property_that_does_not_exist_minvalue_should_be_returned()
        {
            DynamicEntity entity = GetEmptyEntityForExceptionTests();
            Assert.AreEqual(decimal.MinValue, entity.GetMoneyValueFor("number"));
        }

        [Test]
        public void When_asking_for_the_money_value_of_a_property_that_does_exist_the_correct_amount_should_be_returned()
        {
            DynamicEntity entity = GetValidEntityForTests();
            Assert.AreEqual(100.00m, entity.GetMoneyValueFor("moneyproperty"));
        }

        [Test]
        public void When_asking_for_the_datetime_value_of_a_property_that_does_not_exist_datetime_minvalue_should_be_returned()
        {
            DynamicEntity entity = GetEmptyEntityForExceptionTests();
            Assert.AreEqual(DateTime.MinValue, entity.GetDateTimeValueFor("date"));
        }

        public DynamicEntity GetEmptyEntityForExceptionTests()
        {
            return new DynamicEntity("contact");
        }

        public DynamicEntity GetValidEntityForTests()
        {
            var entity = new DynamicEntity("contact");
            entity.Properties.Add(new KeyProperty("keyproperty", new Key(Guid.NewGuid())));
            entity.Properties.Add(new CrmMoneyProperty("moneyproperty", new CrmMoney(100.00m)));
            entity.Properties.Add(new CrmDecimalProperty("decimalproperty", new CrmDecimal(100.00m)));
            entity.Properties.Add(new CrmFloatProperty("floatproperty", new CrmFloat(100.00d)));
            entity.Properties.Add(new CrmNumberProperty("numberproperty", new CrmNumber(1)));
            entity.Properties.Add(new StringProperty("stringproperty", "testing"));

            Picklist picklist = new Picklist();
            picklist.name = "Test Name";
            picklist.Value = 1;

            entity.Properties.Add(new PicklistProperty("picklistproperty", picklist));

            return entity;
        }
    }
}
